home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
cmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
207 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* cmap -
* Color map support
*
* Paul Haeberli - 1990
*
* exports
*
cmap *newcmap(rbuf,gbuf,bbuf,abuf,ncolors)
void freecmap(map)
void writecmap(name,map)
cmap *readcmap(name)
int colordist(r0,g0,b0,r1,g1,b1)
int cmapcolor(map,c)
void cmapsample(map,ci,c)
void printcmap(map)
*
*/
#include "image.h"
#include "vect.h"
#include "cmap.h"
cmap *newcmap(rbuf,gbuf,bbuf,abuf,ncolors)
short *rbuf, *gbuf, *bbuf, *abuf;
int ncolors;
{
cmap *map;
map = (cmap *)mymalloc(sizeof(cmap));
map->ncolors = ncolors;
map->r = (short *)mymalloc(ncolors*sizeof(short));
bcopy(rbuf,map->r,ncolors*sizeof(short));
map->g = (short *)mymalloc(ncolors*sizeof(short));
bcopy(gbuf,map->g,ncolors*sizeof(short));
map->b = (short *)mymalloc(ncolors*sizeof(short));
bcopy(bbuf,map->b,ncolors*sizeof(short));
if(abuf) {
map->nchans = 4;
map->a = (short *)mymalloc(ncolors*sizeof(short));
bcopy(abuf,map->a,ncolors*sizeof(short));
} else {
map->nchans = 3;
map->a = 0;
}
return map;
}
void freecmap(map)
cmap *map;
{
free(map->r);
free(map->g);
free(map->b);
if(map->nchans>3)
free(map->a);
free(map);
}
void writecmap(name,map)
char *name;
cmap *map;
{
IMAGE *image;
image=iopen(name,"w",RLE(1),3,map->ncolors,1,map->nchans);
putrow(image,map->r,0,0);
putrow(image,map->g,0,1);
putrow(image,map->b,0,2);
if(map->nchans>3)
putrow(image,map->a,0,3);
iclose(image);
}
cmap *readcmap(name)
char *name;
{
IMAGE *image;
cmap *map;
int ncolors;
map = (cmap *)mymalloc(sizeof(cmap));
image=iopen(name,"r");
if(!image) {
fprintf(stderr,"readcmap: can't open input file %s\n",name);
exit(1);
}
ncolors = image->xsize;
map->ncolors = ncolors;
map->nchans = image->zsize;
map->r = (short *)mymalloc(ncolors*sizeof(short));
getrow(image,map->r,0,0%image->zsize);
map->g = (short *)mymalloc(ncolors*sizeof(short));
getrow(image,map->g,0,1%image->zsize);
map->b = (short *)mymalloc(ncolors*sizeof(short));
getrow(image,map->b,0,2%image->zsize);
if(image->zsize>3) {
map->a = (short *)mymalloc(ncolors*sizeof(short));
getrow(image,map->a,0,3%image->zsize);
}
iclose(image);
return map;
}
int colordist(r0,g0,b0,r1,g1,b1)
int r0,g0,b0,r1,g1,b1;
{
int dist, dr, dg, db;
dr = 100*(r0-r1);
dg = 100*(g0-g1);
db = 100*(b0-b1);
dist = 0;
if(dr<0)
dist -= dr;
else
dist += dr;
if(dg<0)
dist -= dg;
else
dist += dg;
if(db<0)
dist -= db;
else
dist += db;
return dist;
}
int cmapcolor(map,c)
cmap *map;
vect *c;
{
short *rmap, *gmap, *bmap;
int rwant, gwant, bwant;
int i, min, dist, slot;
rwant = c->x*255.0;
gwant = c->y*255.0;
bwant = c->z*255.0;
rmap = map->r;
gmap = map->g;
bmap = map->b;
min = 1000000;
for(i=0; i<map->ncolors; i++) {
dist = colordist(rwant,gwant,bwant,rmap[i],gmap[i],bmap[i]);
if(dist<min) {
min = dist;
slot = i;
}
}
c->x = rmap[slot]/255.0;
c->y = gmap[slot]/255.0;
c->z = bmap[slot]/255.0;
return slot;
}
void cmapsample(map,ci,c)
cmap *map;
int ci;
vect *c;
{
if(ci<map->ncolors) {
c->x = map->r[ci]/255.0;
c->y = map->g[ci]/255.0;
c->z = map->b[ci]/255.0;
if(map->nchans>3)
c->z = map->a[ci]/255.0;
}
}
void printcmap(map)
cmap *map;
{
int i;
short *rptr, *gptr, *bptr, *aptr;
printf("cmap colors %d\n",map->ncolors);
rptr = map->r;
gptr = map->g;
bptr = map->b;
aptr = map->a;
if(map->nchans == 4) {
for(i=0; i<map->ncolors; i++) {
printf("pos %d: %3d %3d %3d %3d\n",i,*rptr++,*gptr++,*bptr++,*aptr++);
}
} else {
for(i=0; i<map->ncolors; i++) {
printf("pos %d: %3d %3d %3d\n",i,*rptr++,*gptr++,*bptr++);
}
}
}